const express = require("express");
const app = express();
const https = require('https');
const fs = require('fs');
const path = require('path');
const cors = require("cors");
const compression = require('compression');
const rateLimit = require('express-rate-limit');
const morgan = require('morgan');
const helmet = require('helmet');
const jx = require('./jwt');
const config = require('./databaseConfig/index');
require('dotenv').config();
const { CODE, Response } = require('./utils/response');

// 安全头设置
app.use(helmet({
  crossOriginResourcePolicy: { policy: "cross-origin" },
  crossOriginEmbedderPolicy: false
}));

// 启用 GZIP 压缩
app.use(compression());

// 速率限制
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 100 // 限制每个IP 15分钟内最多100个请求
});
app.use(limiter);

// CORS 配置
app.use(cors({
  origin: function(origin, callback) {
    // 允许来自任何源的请求，或者你可以指定具体的源
    callback(null, true);
  },
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
  exposedHeaders: ['Content-Range', 'X-Content-Range'],
  maxAge: 86400 // 预检请求缓存1天
}));

// 预检请求处理
app.options('*', cors({
  origin: true,
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
  maxAge: 86400
}));

app.use(express.urlencoded({ extended: false }));
app.use(express.json({ limit: '10mb' }));

// 使用 morgan 进行日志记录
app.use(morgan('[:date[clf]] :method :url :status :response-time ms - :res[content-length]'));

// 白名单路由配置
const whitelistedRoutes = ['/user/login','/user/wxLogin'];

// Token 验证中间件
async function checkToken(req, res, next) {
  // 检查是否是白名单路由
  if (whitelistedRoutes.includes(req.path)) {
    return next();
  }

  let token = req.headers.authorization?req.headers.authorization:"";
  
  if (!token) {
    return res.status(CODE.UNAUTHORIZED)
      .json(Response.error(CODE.UNAUTHORIZED, '未携带 token'));
  }
  if (token && token.startsWith('Bearer')) {
       let regex = /^Bearer\s+(.*)$/;
let match = token.match(regex);
 
// 如果匹配成功，match[1]将包含token部分
if (match) {
     token = match[1];
} else {
    console.log('Authorization header does not start with "Bearer " or is invalid.');
}
  }



  try {
    const decoded = await jx.verifyJWT(token);
    console.log(decoded.exp);
    
    const currentTimestamp = Math.floor(Date.now() / 1000);
    
    if (decoded.exp && decoded.exp < currentTimestamp) {
      throw new Error('登录已过期');
    }
    
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(CODE.UNAUTHORIZED)
      .json(Response.error(CODE.UNAUTHORIZED, err.message));
  }
}

// 错误处理中间件
function errorHandler(err, req, res, next) {
  console.error(`[Error] ${err.stack}`);
  
  // 根据错误类型设置适当的状态码
  let statusCode = err.status || CODE.SERVER_ERROR;
  let message = err.message;

  // 处理特定类型的错误
  if (err.name === 'ValidationError') {
    statusCode = CODE.VALIDATE_ERROR;
  } else if (err.name === 'UnauthorizedError') {
    statusCode = CODE.UNAUTHORIZED;
  } else if (err.name === 'ForbiddenError') {
    statusCode = CODE.FORBIDDEN;
  }

  // 在生产环境下隐藏详细错误信息
  if (process.env.NODE_ENV === 'production' && statusCode === CODE.SERVER_ERROR) {
    message = ERROR_MSG[CODE.SERVER_ERROR];
  }

  res.status(statusCode).json(Response.error(
    statusCode,
    message,
    process.env.NODE_ENV !== 'production' ? err.stack : undefined
  ));
}

// 修改静态文件服务配置
app.use('/public', (req, res, next) => {
  res.set({
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With',
    'Access-Control-Allow-Credentials': 'true'
  });
  next();
}, express.static(path.join(__dirname, 'public'), {
  maxAge: '1d',
  etag: true,
  setHeaders: (res, path, stat) => {
    res.set('Cross-Origin-Resource-Policy', 'cross-origin');
  }
}));

// 路由配置
const routes = {
  admin: require("./routes/admin"),
  user: require("./routes/user"),
  upload: require("./routes/upload"),
  company: require("./routes/company")
};

// 修改 404 处理中间件 - 移到 API 路由之前
app.use( (req, res, next) => {
  // 检查请求的路径是否匹配任何已定义的路由
  
  const path = req.path.replace('/BHapi', '');
  const routeExists = Object.values(routes).some(router => {
    return router.stack.some(layer => {
      if (layer.route) {
        const routePath = layer.route.path;
        return path === routePath || path.startsWith(routePath + '/');
      }
      return false;
    });
  });

  if (!routeExists) {
    return res.status(CODE.NOT_FOUND)
      .json(Response.error(CODE.NOT_FOUND, `接口 ${req.originalUrl} 不存在`));
  }
  next();
});

// API 路由
app.use("/BHapi", 
  checkToken,
  Object.values(routes)
);

// 其他路径的 404 处理
app.use((req, res) => {
  console.log(`404 Not Found: ${req.originalUrl}`);
  res.status(CODE.NOT_FOUND)
    .json(Response.error(CODE.NOT_FOUND, `路径 ${req.originalUrl} 不存在`));
});

// 错误处理
app.use(errorHandler);

// // 添加 SSL 证书配置
// const SSL_OPTIONS = {  
//   key: fs.readFileSync('./ssl/ssl.key'), // 私钥文件路径  
//   cert: fs.readFileSync('./ssl/ssl.crt') // 证书文件路径  
//   // 可以添加ca, 如果有CA证书链  
// };  
const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`API server running at http://127.0.0.1:${PORT}`);
});
